﻿(*  
    F# Dataflow for ViewModels
    (c) Andras Janko, 2013, Available under Microsoft Public License.
*)

namespace FsFlow

open System
open System.Collections.Generic
open System.Windows.Input

/// Published variable
type IVariableP =
    inherit IComparable
    inherit IDisposable
    abstract Ticket: Ticket
    abstract Trigger: obj -> unit
    
/// Publishable and mappable variable
type IVariable<'a> =
    abstract Value: 'a with get, set
    abstract AddDependent: IVariableP -> unit
    abstract RemoveDependent: IVariableP -> unit

/// Inner object in a variable computation
type IPath =
    inherit IVariableP
    abstract Refresh: unit -> unit     
//    abstract ValueExpired: bool with get, set
    
/// Generic inner object in a variable computation
type IPath<'a> =
    inherit IPath
    abstract Value: 'a
    abstract Initialize: Ticket * IVariable<'a> option -> unit

/// Generic published variable
type IVariableP<'a> =
    inherit IVariableP                
    inherit IVariable<'a>   

/// Variable computation
type IVariableD<'a> =
    inherit IDisposable
    inherit IVariable<'a>

type CommandState =
    | ErrorMessage of string
    | Disabled
    | Enabled
    | EnabledNamed of string

/// CommandState variable published as ICommand
type ICommandP =
    inherit IVariableP<CommandState>
    inherit ICommand
    abstract Name: string
    abstract Error: string

// Collections

type IVariableSetP<'a when 'a: comparison> =
    inherit IVariableP
    abstract TriggerAdd: obj -> 'a -> unit
    abstract TriggerRemove: obj -> 'a -> unit 
    abstract TriggerChange: obj -> 'a Set * 'a Set -> unit
    abstract TriggerClear: obj -> unit

and IVariableSet<'a when 'a: comparison> =
    inherit IVariable<'a Set>
    inherit ICollection<'a>
    abstract Change: 'a Set * 'a Set -> unit
    abstract AddDependentSet: IVariableSetP<'a> -> unit
    abstract RemoveDependentSet: IVariableSetP<'a> -> unit

[<AllowNullLiteral>]
type IChangeList =
    inherit Collections.IList
    abstract Change: Collections.IList * Collections.IList -> unit

type IMappedSet<'a when 'a: comparison> =
    inherit IVariableSetP<'a>
    inherit IPath

//type IVariableListP<'a when 'a: comparison> =
//    inherit IVariableP
//    inherit IVariableList<'a>
//    abstract Inserted: int * 'a -> unit
//    abstract Removed: int -> unit 
//    abstract Changed: int * 'a -> unit
//    abstract Cleared: unit -> unit
//
//and IVariableList<'a when 'a: comparison> =
//    inherit IVariable<'a Set>
//    inherit IList<'a>
//    abstract AddDependentList: IVariableListP<'a> -> unit
//    abstract RemoveDependentList: IVariableListP<'a> -> unit
